package com.kmxd.ams.app.jy;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.kmxd.ams.client.archive.IArchiveTypeSvc;
import com.kmxd.ams.client.jy.IAuthDatabaseSvc;
import com.kmxd.ams.client.jy.IAuthDetailsSvc;
import com.kmxd.ams.client.jy.dto.AuthArchTypeDTO;
import com.kmxd.ams.client.jy.dto.AuthDatabaseAddDTO;
import com.kmxd.ams.client.jy.dto.AuthDatabaseEditDTO;
import com.kmxd.ams.client.jy.dto.AuthDatabaseQueryDTO;
import com.kmxd.ams.client.jy.vo.ArchTypeAuthVO;
import com.kmxd.ams.client.jy.vo.AuthDatabaseListVO;
import com.kmxd.ams.client.jy.vo.AuthDatabaseVO;
import com.kmxd.ams.client.jy.vo.AuthorizationUserVO;
import com.kmxd.ams.client.system.ISysUserSvc;
import com.kmxd.ams.client.system.vo.SysUserVO;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.common.query.QueryGen;
import com.kmxd.ams.core.exception.BizTipException;
import com.kmxd.ams.core.util.IdUtil;
import com.kmxd.ams.infra.archive.entity.ArchiveType;
import com.kmxd.ams.infra.jy.entity.AuthDatabase;
import com.kmxd.ams.infra.jy.entity.AuthDetails;
import com.kmxd.ams.infra.jy.mapper.AuthDatabaseMapper;
import com.kmxd.ams.infra.system.entity.SysUser;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 授权门类信息 服务实现类
 *
 * @author ZuoLG
 * @since 2023-11-30
 */
@Service
@AllArgsConstructor
public class AuthDatabaseSvcImpl extends ServiceImpl<AuthDatabaseMapper, AuthDatabase>
    implements IAuthDatabaseSvc {
  private final ISysUserSvc sysUserSvc;
  private IArchiveTypeSvc archiveTypeSvc;
  private IAuthDetailsSvc authDetailsSvc;

  @Override
  public Page<AuthDatabaseListVO> selectPage(Page reqPage, AuthDatabaseQueryDTO req) {
    LambdaQueryWrapper<AuthDatabase> queryWrapper =
        QueryGen.init(new QueryWrapper<AuthDatabase>(), req).lambda();
    Page<AuthDatabase> page = this.baseMapper.selectPage(reqPage, queryWrapper);
    Page<AuthDatabaseListVO> voPage = BeanUtil.copyProperties(page, Page.class);
    voPage.setRecords(BeanUtil.copyToList(page.getRecords(), AuthDatabaseListVO.class));
    return voPage;
  }

  @Override
  public List<AuthDatabaseListVO> selectList(AuthDatabaseQueryDTO req) {
    LambdaQueryWrapper<AuthDatabase> queryWrapper =
        QueryGen.init(new QueryWrapper<AuthDatabase>(), req).lambda();
    List<AuthDatabase> list = this.baseMapper.selectList(queryWrapper);
    return BeanUtil.copyToList(list, AuthDatabaseListVO.class);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void add(AuthDatabaseAddDTO req) {
    AuthDatabase entity = BeanUtil.copyProperties(req, AuthDatabase.class);
    this.baseMapper.insert(entity);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void edit(AuthDatabaseEditDTO req) {
    AuthDatabase entity = BeanUtil.copyProperties(req, AuthDatabase.class);
    this.baseMapper.updateById(entity);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void remove(String ids) {
    Set<Long> idList = IdUtil.split(ids);
    this.baseMapper.deleteBatchIds(idList);
  }

  @Override
  public AuthDatabaseVO view(Long id) {
    AuthDatabase entity = this.baseMapper.selectById(id);
    return BeanUtil.copyProperties(entity, AuthDatabaseVO.class);
  }

  @Override
  public void setArchAuthByUserId(AuthArchTypeDTO req) {
    if (ObjUtil.isEmpty(req.getUserId())) {
      throw BizTipException.instance(ErrorCode.VALIDATE_NOT_NULL, "操作对象不能为空！");
    }

    SysUser sysUser = sysUserSvc.getById(req.getUserId());
    sysUser.setVisitorNumber(req.getVisitorNumber());
    sysUser.setLoginAuthority(req.getLoginAuthority());
    sysUser.setVisitorTime(req.getVisitorTime());
    sysUser.setScopeArchiving(req.getScopeArchiving());
    Integer textBrowsing =
        NumberUtil.isInteger(req.getTextBrowsingOpen())
            ? Integer.valueOf(req.getTextBrowsingOpen())
            : null;
    sysUser.setTextBrowsing(textBrowsing);
    sysUserSvc.updateById(sysUser);
    sysUserSvc.clearAllCache();

    List<Long> archTypeIds = Lists.newArrayList();
    List<AuthDatabase> saveList =
        req.getAuthDatabase().stream()
            .map(
                item -> {
                  AuthDatabase authDatabase = BeanUtil.copyProperties(item, AuthDatabase.class);
                  authDatabase.setUserId(req.getUserId());
                  authDatabase.setArchivesId(item.getArchivesId());
                  authDatabase.setArchivesName(item.getArchivesName());
                  archTypeIds.add(item.getArchivesId());
                  return authDatabase;
                })
            .collect(Collectors.toList());

    LambdaQueryWrapper<AuthDatabase> deleteWrapper = Wrappers.lambdaQuery();
    deleteWrapper.eq(AuthDatabase::getUserId, req.getUserId());
    this.baseMapper.delete(deleteWrapper);

    // 删除不是此门类的个人数据
    if (!archTypeIds.isEmpty()) {
      LambdaQueryWrapper<AuthDetails> deleteArchWrapper = Wrappers.lambdaQuery();
      deleteArchWrapper.eq(AuthDetails::getUserId, req.getUserId());
      deleteArchWrapper.notIn(AuthDetails::getArchivesId, archTypeIds);
      authDetailsSvc.getBaseMapper().delete(deleteArchWrapper);
    }

    this.saveBatch(saveList);


  }

  @Override
  public AuthorizationUserVO getAuthByUserId(Long userId) {
    AuthorizationUserVO authInfo = new AuthorizationUserVO();
    if (ObjectUtil.isEmpty(userId)) {
      return authInfo;
    }
    SysUserVO userVO = sysUserSvc.view(userId);
    authInfo.setUserInfo(userVO);

    LambdaQueryWrapper<AuthDatabase> queryWrapper = Wrappers.lambdaQuery();
    queryWrapper.eq(AuthDatabase::getUserId, userId);
    List<AuthDatabase> list = this.baseMapper.selectList(queryWrapper);
    List<AuthDatabaseListVO> authList = BeanUtil.copyToList(list, AuthDatabaseListVO.class);

    List<ArchiveType> archiveTypes = archiveTypeSvc.list(Wrappers.emptyWrapper());
    List<ArchTypeAuthVO> archTypes = BeanUtil.copyToList(archiveTypes, ArchTypeAuthVO.class);


    LambdaQueryWrapper<AuthDetails> qw = Wrappers.lambdaQuery();
    qw.eq(AuthDetails::getUserId, userId);
    List<AuthDetails> authArchList = this.authDetailsSvc.list(qw);

    archTypes.forEach(
        item -> {
          AuthDatabaseListVO authDb =
              authList.stream()
                  .filter(x -> ObjectUtil.equals(x.getArchivesId(), item.getId()))
                  .findFirst()
                  .orElse(null);
          item.setAuthInfo(authDb);
          List<AuthDetails> authArchs =
                  authArchList.stream()
                          .filter(x -> ObjectUtil.equals(x.getArchivesId(), item.getId()))
                          .collect(Collectors.toList());

          item.setArchNum(authArchs.size());
        });

    authInfo.setArchAuths(archTypes);
    return authInfo;
  }
}
